package org.finesys.common.log.trace.reflect;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.compress.utils.Sets;
import org.finesys.common.log.trace.proxy.AroundLogProxyChain;
import org.finesys.common.log.trace.spi.ExtensionLoader;
import org.finesys.common.log.trace.util.LogstashUtil;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Set;

@Slf4j
public class ReflectHandler {

    private final Set<String> spiName = Sets.newHashSet();


    private ReflectHandler() {
        spiName.add("java.util.Map");
        spiName.add("java.util.List");
        spiName.add("java.util.Set");
        spiName.add("javax.servlet.http.HttpServletRequest");
    }

    /**
     * 获取单例对象
     */
    public static ReflectHandler getInstance() {
        return ReflectHandlerHolder.INSTANCE;
    }

    /**
     * 请求参数解析
     *
     * @param chain chain
     * @return 请求参数
     */
    public Object getRequestParameter(final AroundLogProxyChain chain) {
        List<Object> list = Lists.newArrayList();
        chain.parameter().forEach((k, v) -> {
            v.forEach(o -> {
                try {
                    list.add(ExtensionLoader.getExtensionLoader(Reflect.class).getJoin(spiName.contains(k) ? k : "default").reflect(o));
                } catch (UnsupportedEncodingException e) {
                    log.error(LogstashUtil.exceptionMarker(), "UnsupportedEncodingException", e);
                }

            });
        });
        return list;
    }


    /**
     * 响应参数解析
     *
     * @param o object
     * @return 响应参数
     */
    public Object getResponseParameter(final Object o) {
        Object result = null;
        try {
            result = ExtensionLoader.getExtensionLoader(Reflect.class)
                    .getJoin(spiName.contains(o.getClass().getName()) ? o.getClass().getName() : "default")
                    .reflect(o);
        } catch (UnsupportedEncodingException e) {
            log.error(LogstashUtil.exceptionMarker(), "UnsupportedEncodingException", e);
        }
        return result;
    }

    /**
     * 内部类懒加载
     */
    private static class ReflectHandlerHolder {
        private static final ReflectHandler INSTANCE = new ReflectHandler();
    }
}
